#ifndef _DRIVER_H_
#define _DRIVER_H_

#include <stdarg.h>

/// <summary>
/// MACROS
/// </summary>
#define GAL_CONNECTED       0x01
#define GAL_CONNECTOR_DVI   0x02
#define GAL_CONNECTOR_VGA   0x03
#define GAL_CONNECTOR_TVOUT 0x04
#define GAL_SURFACE_DETPH_08BPP 0x01 //  8 bits per pixel.
#define GAL_SURFACE_DETPH_16BPP 0x02 // 16 bits per pixel.
#define GAL_SURFACE_DETPH_24BPP 0x03 // 24 bits per pixel.
#define GAL_SURFACE_DETPH_32BPP 0x04 // 32 bits per pixel.
#define GAL_MAX_DISPLAYS    8

/// <summary>
/// GAL Surface
/// </summary>
typedef struct _Surface
{
	int left;
	int top;
	int width;
	int height;
	int state;
	void* data;
	void* private;
	int bpp;

} Surface, *SurfacePtr;

/// <summary>
/// GAL Framebuffer
/// </summary>
typedef struct _Framebuffer
{
	int left;
	int top;
	int width;
	int height;
	int state;
	int stride;
	int bpp;
	int start;
	int len;
	void* base;
	void* private;
	Surface surface;

} Framebuffer, *FramebufferPtr;

/// <summary>
/// GAL Context
/// </summary>
typedef struct _Context
{
	int left;
	int top;
	int width;
	int height;
	int state;
	void* private;

} Context, *ContextPtr;

/// <summary>
/// Driver Object
/// </summary>
typedef struct _Driver
{
	int state;
	const char* name;
	void* framebuffer;
	int (*Open)(void);
	int (*CreateCursor)(void);
	int (*ShowCursor)(void);
	int (*HideCursor)(void);
	int (*MoveCursor)(int x, int y);
	int (*DestroyCursor)(void);
	int (*CreateContext)(ContextPtr ctx);
	int (*DestroyContext)(ContextPtr ctx);
	int (*CreateSurface)(void);
	int (*ResizeSurface)(SurfacePtr surface);
	int (*DestroySurface)(SurfacePtr surface);
	int (*FillSurface)(SurfacePtr surface, int color);
	int (*BlitSurface)(SurfacePtr src, SurfacePtr dst);
	int (*CreateFramebuffer)(FramebufferPtr framebuffer);
	int (*DrawLine)(SurfacePtr sfo);
	int (*GradientFill)(SurfacePtr sfo);
	int (*SwapBuffers)(SurfacePtr sfo);
	int (*SetDisplayMode)(void);
	int (*Close)(void);

} Driver, *DriverPtr;

/// <summary>
/// GAL Cursor
/// </summary>
typedef struct _Cursor
{
	int x;
	int y;
	int width;
	int height;
	float scale_x;
	float scale_y;
	void* private;
	SurfacePtr surface;
	DriverPtr drv;
	int state;

} Cursor, *CursorPtr;

/// <summary>
/// GAL Display
/// </summary>
typedef struct _Display
{
	int x;
	int y;
	int width;
	int height;
	int connection;
	DriverPtr drv;
	void* private;
	int state;

} Display, *DisplayPtr;

/// <summary>
/// Generic Framebuffer
/// </summary>
extern int FBDOpen(void);
extern int FBDCreateFramebuffer(FramebufferPtr fbo);

/// <summary>
/// Generic Mouse
/// </summary>
extern int MOUInit(void);
extern void* MOUThread(void* arg);
extern int MOUExit(void);

/// <summary>
/// Methods
/// </summary>
extern int DRVInit(void);
extern int FBDInit(DriverPtr drv);
extern int DRMInit(DriverPtr drv);
extern int DRMLoadModule(const char *name);
extern int DRMDebugPrint(const char *format, va_list ap);
extern int DRMCreateFramebuffer(FramebufferPtr fbo);
extern int DRVOpen(void);
extern int DRVCreateFramebuffer(void);
extern int DRVExit(void);

#endif